﻿namespace ZYCommon
{
    using System;
    using System.Collections;
    using System.Drawing;
    using System.Reflection;
    using System.Windows.Forms;

    public class TableControl : UserControl
    {
        private bool bolAcceptsTab = true;
        private bool bolFullRowSelect = false;
        private bool bolMultiSelect = false;
        private bool bolResentSetCurrentCell = false;
        private int intDefaultRowHeight = 0x10;
        private CellEditStyleConst intEditStyle = CellEditStyleConst.EditBox;
        private Color intGridColor = SystemColors.ControlDarkDark;
        private ArrayList myCols = new ArrayList();
        private ComboBox myComboBox;
        private TableCell myCurrentCell = null;
        private ArrayList myRows = new ArrayList();
        private StringFormat myStrFormat = new StringFormat(StringFormat.GenericTypographic);
        private TextBox myTextBox;
        private static Keys[] myInputKeys = new Keys[] { Keys.Left, Keys.Up, Keys.Right, Keys.Down, Keys.Tab, Keys.Return, Keys.ShiftKey, Keys.Control };

        public TableControl()
        {
            this.AutoScroll = true;
            base.AutoScrollMargin = new Size(4, 4);
            this.myStrFormat.FormatFlags = StringFormatFlags.NoWrap;
            this.BackColor = SystemColors.Window;
            this.myTextBox = new TextBox();
            this.myTextBox.BorderStyle = BorderStyle.None;
            this.myTextBox.Multiline = false;
            this.myTextBox.Visible = false;
            base.Controls.Add(this.myTextBox);
            this.myTextBox.LostFocus += new EventHandler(this.InnerControl_LostFocus);
            this.myTextBox.KeyDown += new KeyEventHandler(this.InnerControl_KeyDown);
            this.myComboBox = new ComboBox();
            this.myComboBox.Visible = false;
            base.Controls.Add(this.myComboBox);
            this.myComboBox.LostFocus += new EventHandler(this.InnerControl_LostFocus);
            this.myComboBox.KeyDown += new KeyEventHandler(this.InnerControl_KeyDown);
        }

        public TableCell AddCell(string strText, int RowIndex, int ColIndex)
        {
            TableCell cell = new TableCell();
            cell.Table = this;
            cell.Row = (TableRow) this.myRows[RowIndex];
            cell.Col = (TableCol) this.myCols[ColIndex];
            cell.Text = strText;
            cell.Row.Cells.Add(cell);
            return cell;
        }

        public TableCol AddCol(int vWidth)
        {
            TableCol col = new TableCol();
            col.Width = vWidth;
            col.Table = this;
            this.myCols.Add(col);
            return col;
        }

        public TableRow AddRow()
        {
            return this.AddRow(false);
        }

        public TableRow AddRow(bool FullCells)
        {
            TableRow row = new TableRow();
            this.myRows.Add(row);
            row.Height = this.intDefaultRowHeight;
            row.BackColor = this.BackColor;
            row.Table = this;
            if (FullCells)
            {
                foreach (TableCol col in this.myCols)
                {
                    TableCell cell = new TableCell();
                    cell.Table = this;
                    cell.Row = row;
                    cell.Col = col;
                    row.Cells.Add(cell);
                }
            }
            return row;
        }

        private void DrawTableRow(TableRow myRow, Graphics myGraph, Rectangle ClipRect)
        {
            if (((myRow.Top + myRow.Height) >= ClipRect.Top) && (myRow.Top <= ClipRect.Bottom))
            {
                SolidBrush brush = new SolidBrush(this.BackColor);
                Pen pen = new Pen(this.intGridColor);
                SolidBrush brush2 = new SolidBrush(SystemColors.WindowText);
                myGraph.DrawLine(pen, ClipRect.Left, myRow.Top, ClipRect.Right, myRow.Top);
                foreach (TableCol col in this.myCols)
                {
                    if (((col.Left + col.Width) >= ClipRect.Left) && (col.Left <= ClipRect.Right))
                    {
                        myGraph.DrawLine(pen, col.Left, myRow.Top, col.Left, myRow.Top + myRow.Height);
                    }
                }
                foreach (TableCell cell in myRow.Cells)
                {
                    Rectangle bounds = cell.Bounds;
                    if (ClipRect.IntersectsWith(bounds))
                    {
                        Color backColor = cell.BackColor;
                        if (!backColor.Equals(Color.Transparent))
                        {
                            if (!brush.Color.Equals(backColor))
                            {
                                brush.Dispose();
                                brush = new SolidBrush(backColor);
                            }
                            myGraph.FillRectangle(brush, bounds);
                        }
                        myGraph.DrawRectangle(pen, bounds);
                        myGraph.DrawString(cell.Text, this.Font, brush2, new RectangleF((float) (bounds.Left + 2), (float) (bounds.Top + 2), (float) (bounds.Width - 2), (float) (bounds.Height - 2)), this.myStrFormat);
                        Rectangle buttonBounds = cell.ButtonBounds;
                        switch (cell.EditStyle)
                        {
                            case CellEditStyleConst.UpDown:
                                goto Label_020A;

                            case CellEditStyleConst.DropDown:
                            case CellEditStyleConst.DropDownEdit:
                            {
                                ControlPaint.DrawComboButton(myGraph, buttonBounds, ButtonState.Flat);
                                continue;
                            }
                            case CellEditStyleConst.Custom:
                            {
                                continue;
                            }
                        }
                    }
                    continue;
                Label_020A:;
                }
                brush.Dispose();
                pen.Dispose();
                brush2.Dispose();
            }
        }

        public TableCell GetCell(int row, int col)
        {
            if ((row >= 0) && (row < this.myRows.Count))
            {
                TableRow row2 = (TableRow) this.myRows[row];
                if ((col >= 0) && (col < row2.Cells.Count))
                {
                    return (TableCell) row2.Cells[col];
                }
            }
            return null;
        }

        public TableCol GetCol(int index)
        {
            return (TableCol) this.myCols[index];
        }

        public int GetColLeft(TableCol vCol)
        {
            int num = 0;
            foreach (TableCol col in this.myCols)
            {
                if (col == vCol)
                {
                    return num;
                }
                num += col.Width;
            }
            return num;
        }

        public int GetRowTop(TableRow vRow)
        {
            int num = 0;
            foreach (TableRow row in this.myRows)
            {
                if (row == vRow)
                {
                    return num;
                }
                num += row.Height;
            }
            return num;
        }

        public TableCell HitTest(Point p)
        {
            return this.HitTest(p.X, p.Y);
        }

        public TableCell HitTest(int x, int y)
        {
            x -= base.AutoScrollPosition.X;
            y -= base.AutoScrollPosition.Y;
            foreach (TableRow row in this.myRows)
            {
                if ((row.Top <= y) && (row.Bottom > y))
                {
                    foreach (TableCell cell in row.Cells)
                    {
                        if ((cell.Col.Left <= x) && (cell.Col.Right > x))
                        {
                            return cell;
                        }
                    }
                    break;
                }
            }
            return null;
        }

        private void InnerControl_KeyDown(object sender, KeyEventArgs e)
        {
            if ((sender == this.myTextBox) && (e.KeyCode == Keys.Return))
            {
                this.InnerControl_LostFocus(sender, null);
            }
        }

        private void InnerControl_LostFocus(object sender, EventArgs e)
        {
            if ((sender == this.myTextBox) && this.myTextBox.Visible)
            {
                if (this.myCurrentCell != null)
                {
                    this.myCurrentCell.Text = this.myTextBox.Text;
                }
                this.myTextBox.Visible = false;
            }
        }

        protected override bool IsInputKey(Keys keyData)
        {
            if ((keyData != Keys.Tab) || this.bolAcceptsTab)
            {

                for (int i = 0; i < myInputKeys.Length; i++)
                {
                    if (keyData == myInputKeys[i])
                    {
                        return true;
                    }
                }
            }
            return base.IsInputKey(keyData);
        }

        protected override void OnClick(EventArgs e)
        {
            Point p = base.PointToClient(Control.MousePosition);
            TableCell cell = this.HitTest(p);
            if (this.myTextBox.Visible)
            {
                this.InnerControl_LostFocus(this.myTextBox, null);
            }
            if (this.myCurrentCell != cell)
            {
                this.CurrentCell = cell;
                switch (this.myCurrentCell.EditStyle)
                {
                    case CellEditStyleConst.DropDown:
                    case CellEditStyleConst.DropDownEdit:
                        if ((this.myCurrentCell.ButtonBounds.Contains(p) && (this.myCurrentCell.Col.DropDownListItems != null)) && (this.myCurrentCell.Col.DropDownListItems.Count > 0))
                        {
                            using (ZYPopupList list = new ZYPopupList())
                            {
                                list.AddObjects(this.myCurrentCell.Col.DropDownListItems.ToArray());
                                list.SetDefaultSize();
                                Point point2 = this.ViewPointToScreen(this.myCurrentCell.Left, this.myCurrentCell.Top);
                                point2 = list.GetPopupPos(point2.X, point2.Y, this.myCurrentCell.Height);
                                list.AutoClose = true;
                                list.ShowPopupList(point2.X, point2.Y, base.FindForm());
                                list.ShowSpell = false;
                                if (list.WaitUserSelected())
                                {
                                    this.myCurrentCell.SelectedObject = list.SelectedItem.obj;
                                    this.myCurrentCell.Text = list.SelectedText;
                                    this.RefreshCell(this.myCurrentCell);
                                }
                            }
                        }
                        break;
                }
            }
            base.Focus();
        }

        protected override void OnDoubleClick(EventArgs e)
        {
            if ((this.myCurrentCell != null) && (this.myCurrentCell.EditStyle != CellEditStyleConst.None))
            {
                Rectangle rectangle = new Rectangle((this.myCurrentCell.Left + 1) + base.AutoScrollPosition.X, (this.myCurrentCell.Top + 1) + base.AutoScrollPosition.Y, this.myCurrentCell.Width - 3, this.myCurrentCell.Height - 3);
                switch (this.myCurrentCell.EditStyle)
                {
                    case CellEditStyleConst.EditBox:
                        this.myTextBox.Bounds = rectangle;
                        this.myTextBox.Text = this.myCurrentCell.Text;
                        this.myTextBox.Visible = true;
                        this.myTextBox.Focus();
                        this.myTextBox.SelectAll();
                        break;

                    case CellEditStyleConst.DropDown:
                        this.myComboBox.Bounds = rectangle;
                        this.myComboBox.Text = this.myCurrentCell.Text;
                        this.myComboBox.Visible = true;
                        this.myComboBox.Focus();
                        this.myComboBox.SelectAll();
                        break;
                }
            }
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            TableCell cell = null;
            switch (e.KeyCode)
            {
                case Keys.Left:
                    if (this.myCurrentCell != null)
                    {
                        cell = this.GetCell(this.myCurrentCell.Row.Index, this.myCurrentCell.Col.Index - 1);
                        break;
                    }
                    cell = this.GetCell(0, 0);
                    break;

                case Keys.Up:
                    if (this.myCurrentCell != null)
                    {
                        cell = this.GetCell(this.myCurrentCell.Row.Index - 1, this.myCurrentCell.Col.Index);
                    }
                    else
                    {
                        cell = this.GetCell(0, 0);
                    }
                    if (cell != null)
                    {
                        this.CurrentCell = cell;
                    }
                    return;

                case Keys.Right:
                    if (this.myCurrentCell != null)
                    {
                        cell = this.GetCell(this.myCurrentCell.Row.Index, this.myCurrentCell.Col.Index + 1);
                    }
                    else
                    {
                        cell = this.GetCell(0, 0);
                    }
                    if (cell != null)
                    {
                        this.CurrentCell = cell;
                    }
                    return;

                case Keys.Down:
                case Keys.Return:
                    if (this.myCurrentCell == null)
                    {
                        cell = this.GetCell(0, 0);
                    }
                    else
                    {
                        cell = this.GetCell(this.myCurrentCell.Row.Index + 1, this.myCurrentCell.Col.Index);
                    }
                    if (cell != null)
                    {
                        this.CurrentCell = cell;
                    }
                    return;

                default:
                    return;
            }
            if (cell != null)
            {
                this.CurrentCell = cell;
            }
        }

        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            if (((e.KeyChar != '\r') && (e.KeyChar != '\t')) && (this.myCurrentCell != null))
            {
                if (this.bolResentSetCurrentCell)
                {
                    this.bolResentSetCurrentCell = false;
                    this.myCurrentCell.Text = "";
                }
                string text = this.myCurrentCell.Text;
                if (text == null)
                {
                    text = "";
                }
                if (e.KeyChar == '\b')
                {
                    if (text.Length > 0)
                    {
                        text = text.Substring(0, text.Length - 1);
                    }
                }
                else
                {
                    text = text + e.KeyChar.ToString();
                }
                this.myCurrentCell.Text = text;
                this.RefreshCell(this.myCurrentCell);
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            Rectangle clipRectangle = e.ClipRectangle;
            Graphics myGraph = e.Graphics;
            clipRectangle.X -= base.AutoScrollPosition.X;
            clipRectangle.Y -= base.AutoScrollPosition.Y;
            myGraph.TranslateTransform((float) base.AutoScrollPosition.X, (float) base.AutoScrollPosition.Y);
            myGraph.ResetClip();
            foreach (TableRow row in this.myRows)
            {
                if (!row.HeadRow)
                {
                    this.DrawTableRow(row, myGraph, clipRectangle);
                }
            }
            if (this.myCurrentCell != null)
            {
                Rectangle bounds = this.myCurrentCell.Bounds;
                if (bounds.IntersectsWith(clipRectangle))
                {
                    using (Pen pen = new Pen(Color.Blue, 2f))
                    {
                        myGraph.DrawRectangle(pen, new Rectangle(bounds.Left - 1, bounds.Top - 1, bounds.Width + 3, bounds.Height + 3));
                    }
                }
            }
            myGraph.ResetTransform();
            clipRectangle = e.ClipRectangle;
            foreach (TableRow row2 in this.myRows)
            {
                if (row2.HeadRow)
                {
                    this.DrawTableRow(row2, myGraph, clipRectangle);
                }
            }
        }

        public void RefreshBounds()
        {
            int num = 0;
            foreach (TableRow row in this.myRows)
            {
                row.Top = num;
                num += row.Height;
            }
            num = 0;
            foreach (TableCol col in this.myCols)
            {
                col.Left = num;
                num += col.Width;
            }
            base.AutoScrollMinSize = new Size(this.TableWidth, this.TableHeight);
        }

        private void RefreshCell(TableCell myCell)
        {
            Rectangle bounds = myCell.Bounds;
            bounds.X += base.AutoScrollPosition.X - 2;
            bounds.Y += base.AutoScrollPosition.Y - 2;
            bounds.Width += 5;
            bounds.Height += 5;
            base.Invalidate(bounds);
        }

        public bool ScrollToView(int x, int y, int width, int height)
        {
            if ((width >= 0) && (height >= 0))
            {
                if (x < 0)
                {
                    x = 0;
                }
                if (y < 0)
                {
                    y = 0;
                }
                int num = 0;
                int num2 = 0;
                Point point = new Point(x, y);
                Size clientSize = base.ClientSize;
                Point autoScrollPosition = base.AutoScrollPosition;
                point = this.ViewPointToClient(point.X, point.Y);
                if (point.X < 0)
                {
                    num = point.X - 3;
                }
                if (point.X > ((clientSize.Width - width) + 3))
                {
                    num = ((point.X - clientSize.Width) + width) + 3;
                }
                if (point.Y < 0)
                {
                    num2 = point.Y - 3;
                }
                if (point.Y > ((clientSize.Height - height) + 3))
                {
                    num2 = ((point.Y - clientSize.Height) + height) + 3;
                }
                if ((num != 0) || (num2 != 0))
                {
                    base.AutoScrollPosition = new Point(num - base.AutoScrollPosition.X, num2 - base.AutoScrollPosition.Y);
                }
                return true;
            }
            return false;
        }

        public Point ViewPointToClient(int x, int y)
        {
            return new Point(x + base.AutoScrollPosition.X, y + base.AutoScrollPosition.Y);
        }

        public Point ViewPointToScreen(int x, int y)
        {
            return base.PointToScreen(this.ViewPointToClient(x, y));
        }

        public bool AcceptsTab
        {
            get
            {
                return this.bolAcceptsTab;
            }
            set
            {
                this.bolAcceptsTab = value;
            }
        }

        public ArrayList Cells
        {
            get
            {
                ArrayList list = new ArrayList();
                foreach (TableRow row in this.myRows)
                {
                    list.AddRange(row.Cells);
                }
                return list;
            }
        }

        public ArrayList Cols
        {
            get
            {
                return this.myCols;
            }
        }

        public TableCell CurrentCell
        {
            get
            {
                return this.myCurrentCell;
            }
            set
            {
                if (this.myTextBox.Visible)
                {
                    this.InnerControl_LostFocus(this.myTextBox, null);
                }
                if (this.myCurrentCell != value)
                {
                    TableCell myCurrentCell = this.myCurrentCell;
                    this.myCurrentCell = value;
                    if (myCurrentCell != null)
                    {
                        this.RefreshCell(myCurrentCell);
                    }
                    this.RefreshCell(this.myCurrentCell);
                    this.ScrollToView(this.myCurrentCell.Left, this.myCurrentCell.Top, this.myCurrentCell.Width, this.myCurrentCell.Height);
                    this.bolResentSetCurrentCell = true;
                }
            }
        }

        public int DefaultRowHeight
        {
            get
            {
                return this.intDefaultRowHeight;
            }
            set
            {
                this.intDefaultRowHeight = value;
            }
        }

        public CellEditStyleConst EditStyle
        {
            get
            {
                return this.intEditStyle;
            }
            set
            {
                this.intEditStyle = value;
            }
        }

        public bool FullRowSelect
        {
            get
            {
                return this.bolFullRowSelect;
            }
            set
            {
                this.bolFullRowSelect = value;
            }
        }

        public Color GridColor
        {
            get
            {
                return this.intGridColor;
            }
            set
            {
                this.intGridColor = value;
            }
        }

        public TableRow this[int index]
        {
            get
            {
                return (TableRow) this.myRows[index];
            }
        }

        public bool MultiSelect
        {
            get
            {
                return this.bolMultiSelect;
            }
            set
            {
                this.bolMultiSelect = value;
            }
        }

        public ArrayList Rows
        {
            get
            {
                return this.myRows;
            }
        }

        public int TableHeight
        {
            get
            {
                int num = 0;
                foreach (TableRow row in this.myRows)
                {
                    num += row.Height;
                }
                return num;
            }
        }

        public int TableWidth
        {
            get
            {
                int num = 0;
                foreach (TableCol col in this.myCols)
                {
                    num += col.Width;
                }
                return num;
            }
        }
    }
}

